<?php

namespace Kangcg\Application\Cache;

use Kangcg\Application\File\File;

/**
 * 文件缓存
 */
class FileCache
{
    const FORMAT = '.back';
    public string $file_logs;
    public $file_suffix = self::FORMAT;

    public function __construct()
    {
        $this->file_logs = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR;
    }

    /**
     * 获取缓存
     * @param string $key
     * @return mixed
     */
    public function get($key)
    {
        if (!$this->has($key)) {
            return null;
        }

        return $this->readData($key);
    }

    /**
     * 设置缓存
     * @param string $key 缓存的key值
     * @param mixed $data 要缓存的数据
     * @param int $expiredTime
     * @return bool
     */
    public function set(string $key, mixed $data, int $expiredTime = 0)
    {
        $expiredTime += $expiredTime > 0 ? time() : 0;
        $filePath = $this->file_logs . $key . $this->file_suffix;
        $json = [
            'data' => $data,
            'expired_time' => $expiredTime
        ];

        return $this->writeData($filePath, $json);
    }

    /**
     * 判断缓存文件是否存在
     * @param $alias
     * @return bool
     */
    public function has($alias)
    {
        $path = $this->file_logs . $alias . $this->file_suffix;
        return file_exists($path);
    }

    /**
     * 清楚缓存
     * */
    public function clear()
    {
        if ($dir = opendir($this->file_logs)) {
            while ($file = readdir($dir)) {
                if (!($file === '.' || $file === '..')) {
                    File::unlink($this->file_logs . $file);
                }
            }
        }
    }

    private function writeData(string $filePath, $data): bool
    {
        $data['write_time'] = time();
        $data = serialize($data);

        return File::write($filePath, $data);
    }

    /**
     * 获取文件保存的数据
     * @param string $key
     * @return array|null
     */
    private function readData($key)
    {
        $path = $this->file_logs . $key . $this->file_suffix;
        if (!$data = File::getContent($path)) {
            return null;
        }

        $data = unserialize($data);
        if ($data['expired_time'] > 0 && $data['expired_time'] < time()) {
            File::unlink($path);
            return null;
        }

        if ($data['data'] instanceof \stdClass) {
            return (array)$data['data'];
        }

        return $data['data'];
    }

    private static $_install = null;
}
